<?php
/**
 * session的封装
 *
 * @since 1.0
 * @package if
 * @subpackage controller.context
 */
class ISession extends IObject {	
	private static $instance;
	
	private function __construct() {
		
	}
	
	/**
	 * 取得当前类的单例
	 *
	 * @return ISession
	 * @since 1.0
	 */
	static function singleton() {
		if (!self::$instance) {
			self::$instance = new self;
		}
		return self::$instance;
	}	
	
	/**
	 * 开启SESSION
	 *
	 * @param string $dir 目录
	 * @return boolean
	 * @since 1.0
	 */
	function start($dir = null) {
		if (!is_null($dir)) {
			session_save_path($dir);
		}
		
		//默认的处理器
		$handler = o("@session.handler");
		if ($handler != "") {
			$class = o("@session.{$handler}.class");
			if ($class != "") {
				$obj = new $class;
				$this->setObjHandler($obj);
			}
		}
		
		if (!isset($_SESSION)) {
			return session_start();
		}
		return true;
	}
	
	/**
	 * 设置一个对象的处理器
	 * 
	 * 可以利用此方法对session进行自定义处理，需要在session处理类中定义"open", "close", "read", "write", "destroy", "gc"等方法，
	 * 也可以用$mapping指定操作和方法的对应关系，比如 array("open" => "myOpen", "close" => "myClose")
	 * 
	 * 方法的参数可以参考 http://www.php.net/manual/en/function.session-set-save-handler.php
	 *
	 * @param object|string $obj 对象或类的名称
	 * @param array $mapping 操作和方法的对应关系
	 * @since 1.0
	 */
	function setObjHandler(&$obj, $mapping = array()) {
		if (!is_object($obj)) {//当作class名称
			$obj = IRegistry::singleton()->single($obj);
		}
		$methods = array("open", "close", "read", "write", "destroy", "gc");
		$result = array();
		foreach ($methods as $method) {
			$_method = isset($mapping[$method])?$mapping[$method]:$method;
			$result[$method] = array($obj, $_method);
		}
		session_set_save_handler($result["open"], $result["close"], $result["read"], $result["write"], $result["destroy"], $result["gc"]);
	}
	
	/**
	 * 检查SESSION是否已经能够开启
	 *
	 * @since 1.0
	 */
	function started() {
		if (!isset($_SESSION)) {
			return $this->start();
		}
		return true;
	}
	
	/**
	 * 取得一个SESSION变量的值
	 *
	 * @param string $var 变量名
	 * @return mixed
	 * @since 1.0
	 */
	function get($var) {
		$this->started();
		return (isset($_SESSION[$var]))?$_SESSION[$var]:null;
	}
	
	/**
	 * 设置一个变量的值
	 *
	 * @param string $name 变量名
	 * @param mixed $value 变量值
	 * @since 1.0
	 */
	function set($name, $value) {
		$this->started();
		$_SESSION = if_array_set($_SESSION, $name, $value);
	}
	
	/**
	 * 取得所有变量值
	 *
	 * @return array
	 * @since 1.0
	 */
	function all() {
		return $this->started() ? $_SESSION : array();
	}
	
	/**
	 * 删除SESSION变量
	 *
	 * @param mixed $var 变量名
	 * @since 1.0
	 */
	function remove($var) {
		$this->started();
		unset($_SESSION[$var]);
	}
	
	/**
	 * 销毁所有SESSION
	 *
	 * @since 1.0
	 */
	function destroy() {
		$this->started();
		session_destroy();
	}
	
	function contains($name) {
		$this->started();
		return array_key_exists($name, $_SESSION);
	}
}

?>